package com.dynamic.mybatis.core.generator.helper;

import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
import com.dynamic.mybatis.core.generator.InjectorHelper;
import com.dynamic.mybatis.core.metadata.MappedStatementField;
import com.dynamic.mybatis.core.metadata.MappedStatementMetaField;
import com.dynamic.mybatis.core.metadata.MappedStatementTable;

import java.util.Objects;
import java.util.Optional;

import static java.util.stream.Collectors.joining;

/**
 * @Description
 * @Author xs
 * @Date 2023/4/14 16:25
 */
public class WhereInjectorHelper extends InjectorHelper {

    /**
     * EntityWrapper方式获取select where
     *
     * @param newLine 是否提到下一行
     * @param table   表信息
     * @return String
     */
    public static String sqlWhereWrapper(boolean newLine, MappedStatementTable table) {
        if (getLogicDelete(table).isPresent()) {
            String sqlScript = WhereInjectorHelper.getAllSqlWhere(table, true, true, null);
//            sqlScript = SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", null),
//                    true);
            sqlScript += (NEWLINE + LogicDeleteHelper.getLogicDeleteSql(table, true, true) + NEWLINE);
            String normalSqlScript = SqlScriptUtils.convertIf(String.format("AND ${%s}", null),
                    String.format("%s != null and %s != '' and %s", null, null,
                            null), true);
            normalSqlScript += NEWLINE;
            normalSqlScript += SqlScriptUtils.convertIf(String.format(" ${%s}", null),
                    String.format("%s != null and %s != '' and %s", null, null,
                            null), true);
            //  sqlScript += normalSqlScript;
            sqlScript = SqlScriptUtils.convertChoose(String.format("%s != null", WRAPPER), sqlScript,
                    LogicDeleteHelper.getLogicDeleteSql(table, false, true));
            sqlScript = SqlScriptUtils.convertWhere(sqlScript);
            return newLine ? NEWLINE + sqlScript : sqlScript;
        } else {
            String sqlScript = WhereInjectorHelper.getAllSqlWhere(table, false, true, null);
//            sqlScript = SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", null), true);
//            sqlScript += NEWLINE;
/*            sqlScript += SqlScriptUtils.convertIf(String.format(SqlScriptUtils.convertIf(" AND", String.format("%s and %s", null, null), false) + " ${%s}", null),
                    String.format("%s != null and %s != '' and %s", null, null,
                            null), true);*/
            sqlScript = SqlScriptUtils.convertWhere(sqlScript) + NEWLINE;
//            sqlScript += SqlScriptUtils.convertIf(String.format(" ${%s}", null),
//                    String.format("%s != null and %s != '' and %s", null, null,
//                            null), true);
//            sqlScript = SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", WRAPPER), true);
            return newLine ? NEWLINE + sqlScript : sqlScript;
        }
    }


    /**
     * 获取所有的查询的 sql 片段
     *
     * @param ignoreLogicDelFiled 是否过滤掉逻辑删除字段
     * @param withId              是否包含 id 项
     * @param prefix              前缀
     * @return sql 脚本片段
     */
    public static String getAllSqlWhere(MappedStatementTable table, boolean ignoreLogicDelFiled, boolean withId, final String prefix) {
        final String newPrefix = prefix == null ? EMPTY : prefix;
        String filedSqlScript = table.getFields().stream()
                .filter(i -> {
                    if (ignoreLogicDelFiled) {
                        return !(i.isLogicDelete());
                    }
                    return !i.isPrimaryKey();
                })
                .map(i -> getSqlWhere(i, newPrefix)).filter(Objects::nonNull).collect(joining(NEWLINE));

        Optional<MappedStatementMetaField> optionalKeyField = getFirstKeyField(table);

        if (!withId || !optionalKeyField.isPresent()) {
            return filedSqlScript;
        }
        MappedStatementField field = optionalKeyField.get();
        String newKeyProperty = newPrefix + field.getField();
        String keySqlScript = field.getColumn() + EQUALS + SqlScriptUtils.safeParam(newKeyProperty);
        return SqlScriptUtils.convertIf(keySqlScript, String.format("%s != null", newKeyProperty), false)
                + NEWLINE + filedSqlScript;
    }

    /**
     * 获取 查询的 sql 片段
     *
     * @param prefix 前缀
     * @return sql 脚本片段
     */
    public static String getSqlWhere(MappedStatementField field, final String prefix) {
        final String newPrefix = prefix == null ? EMPTY : prefix;
        // 默认:  AND column=#{prefix + el}
        String sqlScript = " AND " + String.format(condition, field.getColumn(), newPrefix + field.getField());
        // 查询的时候只判非空
        return convertIf(field, sqlScript, convertIfProperty(newPrefix, field.getField()), whereStrategy);
    }
}